home *** CD-ROM | disk | FTP | other *** search
/ IRIS Performer 2.2 Friends Demo / SGI IRIS Performer 2.2 Friends Demo.iso / friends / medit / pfLoader / Internalstuff / read.c < prev    next >
Text File  |  1997-11-20  |  24KB  |  757 lines

  1. /************************************************************************
  2. Read a Model file
  3. ************************************************************************/
  4.  
  5. /************************************************************************
  6. Materials
  7. ************************************************************************/
  8. static void ReadMaterial(reg FILE *f, reg MaterialPtr m)
  9. {
  10.     int token;
  11.     char name[MaxName];
  12.     while (GetToken(f, &token)) {
  13.     switch (token) {
  14.         case BlockEnd:    return;
  15.         case FMName:    GetStuff(GetString(f, name, MaxName));
  16.                 RenameMaterial(m, name);        break;
  17.         case FMAmbient:    GetStuff(GetFloats(f, m->Ambient, 3));    break;
  18.         case FMDiffuse:    GetStuff(GetFloats(f, m->Diffuse, 3));    break;
  19.         case FMSpecular:    GetStuff(GetFloats(f, m->Specular, 3));    break;
  20.         case FMEmissive:    GetStuff(GetFloats(f, m->Emissive, 3));    break;
  21.         case FMShine:    GetStuff(GetFloats(f, &m->Shine, 1));    break;
  22.         case FMAlpha:    GetStuff(GetFloats(f, &m->Alpha, 1));    break;
  23.         default:        if (!SkipFuture(f)) {
  24.                     SetError(BAD_MATERIAL);
  25.                 }
  26.     }
  27.     }
  28. }
  29. static void ReadMaterials(reg FILE *f)
  30. {
  31.     MaterialPtr m;
  32.     int i, index, token;
  33.  
  34.     while (GetToken(f, &token)) {
  35.     switch (token) {
  36.         case BlockEnd:    return;
  37.  
  38.         case FMat:    m = NewMaterial();
  39.             if (Compatibility < 3.02) {
  40.                 GetStuff(GetByte(f, &index));
  41.             }
  42.             else {
  43.                 GetStuff(GetInt(f, &index));
  44.             }
  45.             if (index >= MatListSize) {
  46.                 int newsize = index+100;
  47.                 if (MatListSize IS 0) {
  48.                 MaterialList = malloc(newsize*sizeof(MaterialPtr));
  49.                 }
  50.                 else {
  51.                 MaterialList = realloc(MaterialList, newsize*sizeof(MaterialPtr));
  52.                 }
  53.                 for (i=MatListSize; i<newsize; i++) {
  54.                 MaterialList[i] = NULL;
  55.                 }
  56.                 MatListSize = newsize;
  57.             }
  58.             MaterialList[index] = m;
  59.             ReadMaterial(f,m);
  60.             AddMaterial(m);
  61.             break;
  62.  
  63.         default:    if (!SkipFuture(f)) {
  64.                 SetError(BAD_MATERIAL);
  65.             }
  66.     }
  67.     }
  68. }
  69. /************************************************************************
  70. Read a texture reference
  71. ************************************************************************/
  72. static void ReadTextureRef(reg FILE *f, flag ReadAttributes)
  73. {
  74.     reg int i;
  75.     float filter;
  76.     reg TexturePtr t;
  77.     char name[MaxFileName];
  78.     int index, token, size, fast, minfilter, magfilter, clampx, clampy, transparent, alphatest;
  79.  
  80.     GetStuff(GetInt(f, &index));
  81.     GetStuff(GetString(f, name, MaxFileName));
  82.  
  83.     if (index >= TexListSize) {
  84.     int newsize = index+100;
  85.     if (TexListSize IS 0) {
  86.         TextureList = malloc(newsize*sizeof(TexturePtr));
  87.     }
  88.     else {
  89.         TextureList = realloc(TextureList, newsize*sizeof(TexturePtr));
  90.     }
  91.     for (i=TexListSize; i<newsize; i++) {
  92.         TextureList[i] = NULL;
  93.     }
  94.     TexListSize = newsize;
  95.     }
  96.  
  97.     t = NewTexture();
  98.     t->File = CopyOfString(name);
  99.     AddTexture(t);
  100.     TextureList[index] = t;
  101.  
  102.     minfilter = MT_NULL;    /* Default values for texture attributes */
  103.     magfilter = MT_NULL;
  104.     fast = FALSE;
  105.     clampx = FALSE;
  106.     clampy = FALSE;
  107.     transparent = FALSE;
  108.     alphatest = 25;
  109.  
  110.     while (ReadAttributes AND GetToken(f, &token)) {
  111.     switch (token) {
  112.         case BlockEnd:    ReadAttributes = FALSE;
  113.                     break;
  114.  
  115.         case FMinFilter:    if (Compatibility < 3.00) {
  116.                     GetStuff(GetSize(f,&size));
  117.                 }
  118.                 GetStuff(GetFloats(f,&filter,1));
  119.                 minfilter = (int)filter;
  120.                 break;
  121.  
  122.         case FMagFilter:    if (Compatibility < 3.00) {
  123.                     GetStuff(GetSize(f,&size));
  124.                 }
  125.                 GetStuff(GetFloats(f,&filter,1));
  126.                 minfilter = (int)filter;
  127.                 break;
  128.  
  129.         case FFastTex:    if (Compatibility < 3.00) {
  130.                     GetStuff(GetSize(f,&size));
  131.                 }
  132.                 GetStuff(GetInt(f, &fast));
  133.                 break;
  134.  
  135.         case FOldClamp:    GetStuff(GetSize(f, &size));
  136.                 GetStuff(GetInt(f, &clampx));
  137.                 clampy = clampx;
  138.                 break;
  139.  
  140.         case FClampTexX:    GetStuff(GetInt(f, &clampx));
  141.                 break;
  142.  
  143.         case FClampTexY:    GetStuff(GetInt(f, &clampy));
  144.                 break;
  145.  
  146.         case FTexTransparent:GetStuff(GetInt(f, &transparent));
  147.                 break;
  148.  
  149.         case FTexAlphaTest:    GetStuff(GetInt(f, &alphatest));
  150.                 break;
  151.  
  152.         default:        if (!SkipFuture(f)) {
  153.                     SetError(BAD_TEXTURE);
  154.                 }
  155.     }
  156.     }
  157.     if (t) {
  158.     t->MinFilter = minfilter;
  159.     t->MagFilter = magfilter;
  160.     t->Fast = fast;
  161.     t->ClampX = clampx;
  162.     t->ClampY = clampy;
  163.     t->Transparent = transparent;
  164.     t->AlphaTest = alphatest;
  165.     }
  166. }
  167. /************************************************************************
  168. Read a vertex table if present in the file
  169. ************************************************************************/
  170. static int VertexTableSize = 0;
  171. static real (*VertexTable)[XYZ] = NULL;
  172. static void ReadVertexTable(reg FILE *f)
  173. {
  174.     int size;
  175.     GetStuff(GetInt(f, &size));
  176.     if (size > VertexTableSize) {
  177.     VertexTableSize = size + 1000;
  178.     if (!VertexTable) {
  179.         VertexTable = malloc(VertexTableSize * sizeof(real) * XYZ);
  180.     }
  181.     else {
  182.         VertexTable = realloc(VertexTable, VertexTableSize * sizeof(real) * XYZ);
  183.     }
  184.     }
  185.     GetReals(f, (real*)VertexTable, size*XYZ);
  186. }
  187. /************************************************************************
  188. Read a vertex
  189. ************************************************************************/
  190. static void ReadVertex(reg FILE *f, PolygonPtr p)
  191. {
  192.     real c[XYZ];
  193.     int token, index;
  194.     reg PolygonBeadPtr pb = NULL;
  195.  
  196.     while (GetToken(f, &token)) {
  197.     switch (token) {
  198.         case BlockEnd:  pb->Owner = p;
  199.                 return;
  200.  
  201.         case FVIndex:   GetStuff(GetInt(f, &index));
  202.                 pb = AddPolygonBead(&(p->FirstBead), VertexTable[index]);
  203.                 AddToVertexList(pb);
  204.                 pb->Colour = LastVertexColour;
  205.                 break;
  206.  
  207.         case FVCoord:   GetStuff(GetReals(f, c, XYZ));
  208.                 pb = AddPolygonBead(&(p->FirstBead), c);
  209.                 AddToVertexList(pb);
  210.                 pb->Colour = LastVertexColour;
  211.                 break;
  212.  
  213.         case FVTexture: GetStuff(GetFloats(f, pb->TextureCoord, XY));
  214.                 break;
  215.  
  216.         case FVNormal:  GetStuff(GetFloats(f, pb->Normal, XYZ));
  217.                 break;
  218.  
  219.         case FVColour:  GetStuff(GetInt(f, (int*)&LastVertexColour));
  220.                 pb->Colour = LastVertexColour;
  221.                 break;
  222.  
  223.         default:        if (!SkipFuture(f)) {
  224.                 SetError(BAD_VERTEX);
  225.                 }
  226.     }
  227.     }
  228. }
  229. /************************************************************************
  230. Read a polygon
  231. ************************************************************************/
  232. static void ReadPolygon(reg FILE *f, reg TreePtr t, PolygonPtr parent)
  233. {
  234.     int token,data;
  235.     reg PolygonPtr p;
  236.  
  237.     p = AddPolygon(NULL, t, parent);
  238.     AddToPolygonList(p);
  239.  
  240.     p->LightGroup = 0;
  241.     p->Texture = LastTexture;
  242.     p->Colour = LastPolyColour;
  243.     p->Material = LastMaterial;
  244.     p->Smooth = p->Coloured = p->Envmapped = FALSE;
  245.  
  246.     while (GetToken(f, &token)) {
  247.     switch (token) {
  248.         case BlockEnd:    if (Compatibility < 402) {
  249.                     p->Coloured = (p->Material IS NULL);
  250.                 }
  251.                 if (!p->Smooth) {
  252.                     reg PolygonBeadPtr pb;
  253.                     reg float x = p->Normal[X];
  254.                     reg float y = p->Normal[Y];
  255.                     reg float z = p->Normal[Z];
  256.                     LoopThroughPolygonsBeads(p, pb) {
  257.                     pb->Normal[X] = x;
  258.                     pb->Normal[Y] = y;
  259.                     pb->Normal[Z] = z;
  260.                     }
  261.                 }
  262.                 return;
  263.  
  264.         case FPolygon:    ReadPolygon(f, t, p);
  265.                 break;
  266.  
  267.         case FPSmooth:    p->Smooth = TRUE;
  268.                 break;
  269.  
  270.         case FPColoured:    p->Coloured = TRUE;
  271.                 break;
  272.  
  273.         case FPMaterial:    GetStuff(GetInt(f, &data));
  274.                 if ((data < 0) OR (data > MatListSize)) {
  275.                     if ((data ISNT -1) OR (data > TexListSize)) {
  276.                     fprintf(stderr, "%s file: bad material index!\n", ProgName);
  277.                     }
  278.                     LastMaterial = NULL;
  279.                 }
  280.                 else {
  281.                     LastMaterial = MaterialList[data];
  282.                 }
  283.                 p->Material = LastMaterial;
  284.                 break;
  285.  
  286.         case FPColour:    GetStuff(GetInt(f, (int*)&LastPolyColour));
  287.                 p->Colour = LastPolyColour;
  288.                 break;
  289.  
  290.         case FPNormal:    GetStuff(GetFloats(f, p->Normal, XYZ));
  291.                 break;
  292.  
  293.         case FPTexture:    GetStuff(GetInt(f, &data));
  294.                 if ((data < 0) OR (data > TexListSize)) {
  295.                     if ((data ISNT -1) OR (data > TexListSize)) {
  296.                     fprintf(stderr, "%s file: bad texture index!\n", ProgName);
  297.                     }
  298.                     LastTexture = NULL;
  299.                 }
  300.                 else {
  301.                     LastTexture = TextureList[data];
  302.                 }
  303.                 p->Texture = LastTexture;
  304.                 break;
  305.  
  306.         case FPEnvmapped:    p->Envmapped = TRUE;
  307.                 break;
  308.  
  309.         case FPLightGroup:    GetStuff(GetInt(f, &(p->LightGroup)));
  310.                 break;
  311.  
  312.         case FVertex:    ReadVertex(f,p);
  313.                 break;
  314.  
  315.         default:        if (!SkipFuture(f)) {
  316.                     SetError(BAD_POLYGON);
  317.                 }
  318.     }
  319.     }
  320. }
  321. /************************************************************************
  322. Read an object's hierarchy data
  323. ************************************************************************/
  324. static void ReadHierarchy(reg FILE *f, reg TreePtr currentbranch, ModelObjectPtr o)
  325. {
  326.     int token;
  327.     reg TreePtr new;
  328.     flag done, across;
  329.     char name[MaxName];
  330.  
  331.     new = NULL;
  332.     done = FALSE;
  333.     across = FALSE;
  334.     until (done OR !GetToken(f, &token)) {
  335.     switch (token) {
  336.         case FNewBranch:        VertexIndex = 0;
  337.                     GetStuff(GetString(f,name,MaxName));            break;
  338.         case FBranchId:        GetStuff(GetInt(f, &(currentbranch->BranchId)));        break;
  339.  
  340.         case FPushBranch:        across = TRUE;                        break;
  341.         case FPopBranch:        currentbranch = GoUp(o->Tree, currentbranch);
  342.                     done = (currentbranch IS NULL);                break;
  343.  
  344.         case FGroupBranch:        new = NewTreeBranch(GroupBranch, name);            break;
  345.         case FPolygonBranch:    new = NewTreeBranch(PolygonBranch, name);            break;
  346.         case FLodBranch:        new = NewTreeBranch(LodBranch, name);            break;
  347.         case FInstanceBranch:   new = NewTreeBranch(InstanceBranch, name);            break;
  348.         case FSwitchBranch:        new = NewTreeBranch(SwitchBranch, name);            break;
  349.         case FDcsBranch:        new = NewTreeBranch(DcsBranch, name);            break;
  350.         case FVRMLBranch:        new = NewTreeBranch(VRMLBranch, name);            break;
  351.         case FSolidBranch:        new = NewTreeBranch(SolidBranch, name);            break;
  352.  
  353.         case FBranchSubType:    GetStuff(GetInt(f, &(currentbranch->SubType)));        break;
  354.  
  355.         case FBranchEyeOpen:    GetStuff(GetByte(f, &(currentbranch->EyeOpen)));        break;
  356.         case FBranchFolded:        GetStuff(GetByte(f, &(currentbranch->Folded)));        break;
  357.         case FBranchVisible:    GetStuff(GetByte(f, &(currentbranch->Visible)));        break;
  358.  
  359.         case FVertexTable:        ReadVertexTable(f);                        break;
  360.         case FPolygon:        ReadPolygon(f, currentbranch, NULL);            break;
  361.         case FBackface:        GetStuff(GetInt(f, &(currentbranch->Backfaced)));        break;
  362.         case FBillboard:        GetStuff(GetInt(f, &(currentbranch->Billboard)));        break;
  363.         case FShareNormals:        GetStuff(GetInt(f, &(currentbranch->ShareNormals)));    break;
  364.         case FBoundingBox:        ReadBoundingBox(f, currentbranch->Min, currentbranch->Max);    break;
  365.         case FTmesh:        ReadTmesh(f, currentbranch);                break;
  366.         case FUnmeshed:        ReadUnmeshed(f, currentbranch);                break;
  367.         case FVertexJoin:        ReadVertexJoin(f, currentbranch);                break;
  368.  
  369.         case FSwitchDistance:   GetStuff(GetReals(f, &(currentbranch->SwitchOut), 1));    break;
  370.         case FInstance:        GetStuff(GetInt(f, &(currentbranch->ObjId)));        break;
  371.         case FVRMLIsInline:        GetStuff(GetInt(f, &(currentbranch->IsInline)));        break;
  372.         case FVRMLInlineName:   GetStuff(GetString(f,name,MaxName));
  373.                     currentbranch->InlineName = CopyOfString(name);        break;
  374.         case FMatrix:        GetStuff(GetMatrix(f, currentbranch->Transformation));    break;
  375.         case FDcsMatrix:        GetStuff(GetMatrix(f, currentbranch->DcsMatrix));        break;
  376.         case FHoldValues:        GetStuff(GetSizedInt(f, ¤tbranch->HoldValues));    break;
  377.         case FVRMLAnchorName:   GetStuff(GetString(f,name,MaxName));
  378.                     currentbranch->VRMLAnchor = CopyOfString(name);        break;
  379.         case FSeqTime:        GetStuff(GetReals(f, &(currentbranch->SeqTime), 1));    break;
  380.         case FSeqType:        GetStuff(GetInt(f, &(currentbranch->SeqType)));        break;
  381.         case FScale:        GetStuff(GetReals(f, &(currentbranch->Scale), 1));        break;
  382.  
  383.         default:            if (!SkipFuture(f)) {
  384.                     SetError(BAD_OBJECT);
  385.                     }
  386.     }
  387.     if (new) {
  388.         if (currentbranch) {
  389.         if (across) {
  390.             currentbranch->Across = new;
  391. #if ITSTHEMODELLER
  392.             new->Back = currentbranch;
  393. #endif
  394.             across = FALSE;
  395.         }
  396.         else {
  397.             currentbranch->Down = new;
  398. #if ITSTHEMODELLER
  399.             new->Up = currentbranch;
  400. #endif
  401.         }
  402.         }
  403.         else {
  404.         o->Tree = new;
  405.         }
  406.         currentbranch = new;
  407.         new = NULL;
  408.     }
  409.     }
  410. }
  411. /************************************************************************
  412. Read an object's engines
  413. ************************************************************************/
  414. static void ReadEngines(reg FILE *f, reg TreePtr currentbranch, ModelObjectPtr o)
  415. {
  416.     int token;
  417.     reg TreePtr new;
  418.     flag done, across;
  419.     char name[MaxName];
  420.  
  421.     new = NULL;
  422.     done = FALSE;
  423.     across = FALSE;
  424.     until (done OR !GetToken(f, &token)) {
  425.     switch (token) {
  426.         case FNewEngine:        GetStuff(GetString(f,name,MaxName));            break;
  427.         case FBranchId:        GetStuff(GetInt(f, &(currentbranch->BranchId)));        break;
  428.  
  429.         case FPushEngine:        across = TRUE;                        break;
  430.         case FPopEngine:        currentbranch = GoUp(o->Engines, currentbranch);
  431.                     done = (currentbranch IS NULL);                break;
  432.  
  433.         case FGroupBranch:        new = NewTreeBranch(GroupBranch, name);            break;
  434.         case FActivator:        new = NewTreeBranch(ActivatorEngine, name);            break;
  435.         case FDeactivator:        new = NewTreeBranch(DeactivatorEngine, name);        break;
  436.  
  437.         case FTimeEngine:        new = NewTreeBranch(TimeEngine, name);            break;
  438.         case FLineEngine:        new = NewTreeBranch(LineEngine, name);            break;
  439.         case FAngleEngine:        new = NewTreeBranch(AngleEngine, name);            break;
  440.         case FWaveEngine:        new = NewTreeBranch(WaveEngine, name);            break;
  441.         case FSensorEngine:        new = NewTreeBranch(SensorEngine, name);            break;
  442.  
  443.         case FScalarEngine:        new = NewTreeBranch(ScalarEngine, name);            break;
  444.         case FSplineEngine:        new = NewTreeBranch(SplineEngine, name);            break;
  445.         case FCompareEngine:    new = NewTreeBranch(CompareEngine, name);            break;
  446.         case FMatrixEngine:        new = NewTreeBranch(GroupBranch, name);            break;
  447.  
  448.         case FSwitchOutput:        new = NewTreeBranch(SwitchOutput, name);            break;
  449.         case FDcsOutput:        new = NewTreeBranch(DcsOutput, name);            break;
  450.         case FConnectTo:        GetStuff(GetInt(f, &(currentbranch->ConnectId)));        break;
  451.  
  452.         case FBranchFolded:        GetStuff(GetByte(f, &(currentbranch->Folded)));        break;
  453.         case FStartActive:        GetStuff(GetByte(f, &(currentbranch->StartActive)));    break;
  454.         case FOutputX:        GetStuff(GetByte(f, &(currentbranch->OutputX)));        break;
  455.         case FOutputY:        GetStuff(GetByte(f, &(currentbranch->OutputY)));        break;
  456.         case FOutputZ:        GetStuff(GetByte(f, &(currentbranch->OutputZ)));        break;
  457.         case FOutputH:        GetStuff(GetByte(f, &(currentbranch->OutputH)));        break;
  458.         case FOutputP:        GetStuff(GetByte(f, &(currentbranch->OutputP)));        break;
  459.         case FOutputR:        GetStuff(GetByte(f, &(currentbranch->OutputR)));        break;
  460.  
  461.         case FNoWaves:        GetStuff(GetReals(f, &(currentbranch->NoWaves), 1));    break;
  462.         case FWaveTime:        GetStuff(GetReals(f, &(currentbranch->WaveTime), 1));    break;
  463.         case FScale:        GetStuff(GetReals(f, &(currentbranch->Scale), 1));        break;
  464.         case FOffset:        GetStuff(GetReals(f, &(currentbranch->Offset), 1));        break;
  465.         case FPhase:        GetStuff(GetReals(f, &(currentbranch->Phase), 1));        break;
  466.         case FSwitchOn:        GetStuff(GetInt(f, &(currentbranch->SwitchOn)));        break;
  467.         case FMotionPath:        ReadPathData(f, &(currentbranch->PathData));        break;
  468.         case FCompareType:        GetStuff(GetSizedInt(f, ¤tbranch->CompareType));    break;
  469.         case FHoldValues:        GetStuff(GetSizedInt(f, ¤tbranch->HoldValues));    break;
  470.  
  471. /* Old stuff for REALAX */
  472.         case FKey:                GetStuff(SkipData(f, 1));                    break;
  473.         case FXConMode:        case FXMinValue:        case FXMaxValue:
  474.         case FYConMode:        case FYMinValue:        case FYMaxValue:
  475.         case FZConMode:        case FZMinValue:        case FZMaxValue:
  476.         case FHConMode:        case FHMinValue:        case FHMaxValue:
  477.         case FPConMode:        case FPMinValue:        case FPMaxValue:
  478.         case FRConMode:        case FRMinValue:        case FRMaxValue:
  479.                                 GetStuff(SkipData(f, 4));    break;
  480.  
  481.         default:            if (!SkipFuture(f)) {
  482.                     SetError(BAD_OBJECT);
  483.                     }
  484.     }
  485.     if (new) {
  486.         if (currentbranch) {
  487.         if (across) {
  488.             currentbranch->Across = new;
  489. #if ITSTHEMODELLER
  490.             new->Back = currentbranch;
  491. #endif
  492.             across = FALSE;
  493.         }
  494.         else {
  495.             currentbranch->Down = new;
  496. #if ITSTHEMODELLER
  497.             new->Up = currentbranch;
  498. #endif
  499.         }
  500.         }
  501.         else {
  502.         o->Engines = new;
  503.         }
  504.         currentbranch = new;
  505.         new->ConnectId = -1;
  506.         new = NULL;
  507.     }
  508.     }
  509. }
  510. /************************************************************************
  511. Read an object
  512. ************************************************************************/
  513. static void ReadObject(reg FILE *f)
  514. {
  515.     real flyspeed;
  516.     ModelObjectPtr o;
  517.     char name[MaxName];
  518.     char exref[MaxFileName];
  519.     int token, index, steps, attributes;
  520.     flag GotSubObject = FALSE, GotLod = FALSE;
  521.  
  522.     GetString(f,name,MaxName);
  523.     o = AddObject(name);
  524.  
  525.     LastTexture = NULL;
  526.     LastMaterial = NULL;
  527.     LastPolyColour = LastVertexColour = DefaultColour;
  528.  
  529.     index = 9;
  530.     steps = 10;
  531.     flyspeed = 1.0;
  532.     attributes = 0;
  533.     while (GetToken(f, &token)) {
  534.     switch (token) {
  535.     case BlockEnd:        if (Compatibility < 400) {
  536.                 FreeSubObjects();
  537.                 RemoveEmptyLods(o);
  538.                 if (attributes & 1) {
  539.                     SetBillboarding(o->Tree);
  540.                 }
  541.                 if (!GotSubObject OR !GotLod) {
  542.                     SetError(BAD_FILE);
  543.                 }
  544.                 }
  545. #if ITSTHEMODELLER
  546.                 else {
  547.                 GenerateObjectStats();
  548.                 }
  549.                 o->Connected = FALSE;   /* Recalculate bounding boxes... */
  550.                 o->FlySpeed = flyspeed;
  551.                 o->GridIndex = index;
  552.                 o->GridSteps = steps;
  553. #endif
  554.                 return;
  555.  
  556.     case FPushBranch:   ReadHierarchy(f, NULL, o);            break;
  557.     case FPushEngine:   ReadEngines(f, NULL, o);            break;
  558.     case FObjectId:        GetStuff(GetInt(f, &(o->Id)));        break;
  559.     case FIsTopLevel:   GetStuff(GetInt(f, &(o->IsTopLevel)));    break;
  560.     case FExrefFile:    GetStuff(GetString(f, exref, MaxFileName));
  561.                 o->File = CopyOfString(exref);
  562.                 ReadExref(o);                break;
  563.  
  564.     case FView:        ReadView(f);                break;
  565.     case FGridIndex:    GetStuff(GetInt(f, &index));        break;
  566.     case FFlySpeed:        GetStuff(GetReals(f, &flyspeed, 1));    break;
  567.     case FGridSteps:    GetStuff(GetInt(f, &steps));        break;
  568.     case FBoundingBox:  ReadBoundingBox(f, o->Min, o->Max);        break;
  569.     case FVConstruction:ReadConstructionVertex(f, o);        break;
  570.  
  571. /* Obsolete but needed for backwards compatibility */
  572.     case FVList:        ReadOldVertices(f);                break;
  573.     case FSubObject:    ReadSubObject(f);    GotSubObject = TRUE;    break;
  574.     case FLod:        ReadLod(f, o);    GotLod = TRUE;        break;
  575.     case FObjAttr:        GetStuff(GetInt(f,&attributes));        break;
  576.  
  577. /* Unknown */
  578.     default:        if (!SkipFuture(f)) {
  579.                 SetError(BAD_FILE);
  580.                 }
  581.     }
  582.     }
  583. }
  584. /************************************************************************
  585. Read data items...
  586. ************************************************************************/
  587. static void ReadDataItem(FILE *f)
  588. {
  589.     int item, size, cid, n;
  590.  
  591.     GetStuff(GetByte(f, &item));
  592.     GetStuff(GetSize(f, &size));
  593.  
  594. #if ITSTHEMODELLER
  595.     if (item IS DSceneGridIndex) {
  596.     GetStuff(GetInt(f,&n));
  597.     RememberSceneGridIndex(n);
  598.     }
  599.     else if (item IS DSceneGridSteps) {
  600.     GetStuff(GetInt(f,&n));
  601.     RememberSceneGridSteps(n);
  602.     }
  603.     else {
  604.     if (ReadingExternal) {
  605.         SkipData(f,size);
  606.     }
  607.     else switch (item) {
  608.         case DCurrentObject:    GetStuff(GetInt(f,&FileObjectId));    break;    
  609.         case DNoViewports:        GetStuff(GetInt(f,&n));
  610.                     if (n ISNT NoViewports) {
  611.                         ChangeNoViewports();
  612.                     }                    break;
  613.         case DObjectIsolated:    GetStuff(GetInt(f,&n));
  614.                     if ((Compatibility < 400) AND !n) {
  615.                         FileObjectId = -1;
  616.                     }                    break;
  617.         case DAnimateWhenMoving:    GetStuff(GetInt(f,&AnimateWhenMoving));    break;
  618.         case DEditingEngines:    GetStuff(GetInt(f,&ShowEngines));    break;
  619.  
  620.         case DFileCreateId:        GetStuff(GetInt(f,&cid));
  621.                     FileCreateId = cid;            break;
  622.         case DFilePublicDomain:    GetStuff(GetInt(f,&FilePublicDomain));    break;
  623.  
  624.         case DFileTitle:        GetString(f,FileTitle,CommentSize);    break;
  625.         case DFileAuthor:        GetString(f,FileAuthor,CommentSize);    break;
  626.         case DFileCompany:        GetString(f,FileCompany,CommentSize);    break;
  627.         case DFileContact:        GetString(f,FileContact,CommentSize);    break;
  628.         case DFileComment1:        GetString(f,FileComment1,CommentSize);    break;
  629.         case DFileComment2:        GetString(f,FileComment2,CommentSize);    break;
  630.         case DFileComment3:        GetString(f,FileComment3,CommentSize);    break;
  631.         case DFileComment4:        GetString(f,FileComment4,CommentSize);    break;
  632.  
  633.         /* Unknown in this revision, throw it away */
  634.         default:            SkipData(f,size);
  635.     }
  636.     }
  637. #else
  638.     if (ReadingExternal) {
  639.     SkipData(f,size);
  640.     }
  641.     else {
  642.     switch (item) {
  643.         case DOriginalFilePath:    GetString(f, mwOriginalPath, MaxFileName);
  644.                     break;
  645.         default:            SkipData(f,size);
  646.     }
  647.     }
  648. #endif
  649. }
  650. /************************************************************************
  651. Read a model file...
  652. ************************************************************************/
  653. #define HeaderMax 200
  654. boolean ReadModel(char *fname)
  655. {
  656.     reg int i;
  657.     reg FILE *f;
  658.     reg flag done;
  659.     int type, token;
  660.     reg ModelObjectPtr o;
  661.     char header[HeaderMax];
  662. #if !ITSTHEMODELLER
  663.     char *path, *name, n[MaxFileName];
  664. #endif
  665.  
  666.     done = FALSE;
  667.     DefineTokens();
  668.     OldScene = NULL;
  669. #if !ITSTHEMODELLER
  670.     mwOriginalPath[0] = '\0';
  671. #endif
  672.     for (i=0; i<MatListSize; i++) {
  673.     MaterialList[i] = NULL;
  674.     }
  675.     for (i=0; i<TexListSize; i++) {
  676.     TextureList[i] = NULL;
  677.     }
  678.     if (!(f = GetReadyForRead(fname))) {
  679.     return FALSE;
  680.     }
  681.  
  682. #if ITSTHEMODELLER
  683.     ResetStorage();
  684.     FileObjectId = -1;
  685. #else
  686.     strcpy(n, fname);
  687.     SplitFileName(n,&path,&name);
  688.     if (!ReadingExternal) {
  689.     strcpy(FilePath, path);
  690.     strcpy(FileName, fname);
  691.     }
  692. #endif
  693.  
  694.     if (fgets(header,HeaderMax,f)) {
  695.     if (sscanf(header,"Compatibility: %f",&Compatibility) IS 1) {
  696.         if (Compatibility IS 1.00) {    /* nb. There will never be any 1.00 files in the    */
  697.         ReadModel100(f, fname);        /* outside world, but we still have some.  :)        */
  698.         }
  699.         else if ((Compatibility >= 2.00) AND (Compatibility <= FileRevision)) {
  700.         GetByte(f, &type);
  701.         if ((type IS BinaryFile) OR (type IS ByteswappedFile)) {
  702.             byteswapped = (BigEndian() AND (type IS ByteswappedFile))
  703.                   OR (!BigEndian() AND (type ISNT ByteswappedFile));
  704.             until (done OR !GetToken(f, &token)) {
  705.             switch (token) {
  706.                 case BlockEnd:        PatchReferences();
  707. #if ITSTHEMODELLER
  708.                         LoopThroughAllObjects(o) {
  709.                             if (o->Id IS FileObjectId) {
  710.                             *CurrentObject() = o;
  711.                             break;
  712.                             }
  713.                         }
  714.                         if (!o) {    /* Not found... */
  715.                             *CurrentObject() = *FirstObject();
  716.                         }
  717. #else
  718.                         SearchForTextures();
  719. #endif
  720.                         done = TRUE;        break;
  721.                 case FMaterials:    ReadMaterials(f);        break;
  722.                 case FTextureRef:   ReadTextureRef(f, TRUE);    break;
  723.                 case FObject:        ReadObject(f);        break;
  724.                 case FData:        ReadDataItem(f);        break;
  725.     
  726.             /* Obsolete but needed for backwards compatibility */
  727.                 case FTextureDir:   ReadTextureDir(f);        break;
  728.                 case FTexture:        ReadTextureRef(f, FALSE);    break;
  729.                 case FPush:        ReadOldScene(f);        break;
  730.                 case FView:        ReadView(f);        break;
  731.         
  732.                 default:        if (!SkipFuture(f)) {
  733.                             SetError(BAD_FILE);
  734.                         }
  735.             }
  736.             }
  737.         }
  738.         else {
  739.             SetError(UNKNOWN_FILE);
  740.         }
  741.         }
  742.         else {
  743.         SetError(BAD_REVISION);
  744.         }
  745.     }
  746.     else {
  747.         SetError(UNKNOWN_FILE);
  748.     }
  749.     }
  750.     else {
  751.     SetError(UNKNOWN_FILE);
  752.     }
  753.     FinishReading(f, Compatibility);
  754.     return !FileError;
  755. }
  756.  
  757.